#include "comm.hpp"

typedef void (*func_t)(); 

/////////////////////////////////////其他进程要完成的某种任务////////////////////////////

void DownLoadTask()
{
    sleep(1);
    std::cout << "正在完成下载任务" << std::endl;
}

void IOTask()
{
    sleep(1);
    std::cout << "正在完成IO任务" << std::endl;
}

void FlushTask()
{
    sleep(1);
    std::cout << "正在完成刷新任务" << std::endl;
}

void loadTaskFunc(std::vector<func_t> &funcMap)
{
    funcMap.push_back(DownLoadTask);
    funcMap.push_back(IOTask);
    funcMap.push_back(FlushTask);
}

//////////////////////////////////////////////////////////////////////////////////////


void creatPipeFiles(std::vector<processEp> &pros)
{
    for (int i = 0; i < PROCESSNUM; ++i)
    {

        std::string nameProcess = NAME_PIPE;
        nameProcess += std::to_string(i);
        bool r = creatFifo(nameProcess);
        assert(r);
        (void)r;

        const char *filename = nameProcess.c_str();
        int wfd = open(filename, O_WRONLY);
        // 创建对象
        processEp proc(nameProcess, wfd);

        pros.push_back(proc);
    }
}


void SendTaskProcess(std::vector<processEp>& pros)
{
    while(true)
    {
        // 随机选择一个任务
        int taskNum = rand() % 3;
        // 随机选择一个进程
        int procNum = rand() % 3;

        ssize_t n = write(pros[procNum]._writeFd,&taskNum,sizeof(int));
        std::cout << "server->client" << procNum << " send task:" << taskNum << std::endl; 
        assert(n > 0);
        sleep(1);
    }
}


void DeletePipe(std::vector<processEp>& pros)
{
    for (int i = 0; i < PROCESSNUM; i++)
    {
        removeFifo(pros[i]._namePipe);
        close(pros[i]._writeFd);//关闭所有读端
    }
}


int main()
{
    MAKE_SRAND();

    std::vector<processEp> pros; // 用数组把其他进程管理起来
    std::vector<func_t> funcMap; // 函数指针数组

    // 创建任务表
    loadTaskFunc(funcMap);
    std::cout << "创建任务表完成\n";
    // 1.建立其他进程个数的管道文件
    creatPipeFiles(pros);
    std::cout << "建立其他进程个数的管道文件完成\n";
    // 2.server进程与其他进程通信(采用负载均衡)
    SendTaskProcess(pros);


    // int num = 1;
    // ssize_t n = write(pros[0]._writeFd,&num,sizeof(int));
    // assert(n > 0);
    // (void)n;

    //先尝试往clien1发信息

    // sleep(10);

    //  清除所有管道
    
    DeletePipe(pros);//可以增加信号捕获

    return 0;
}